﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Management;
using System.Collections;
// namespaces necesarios para conexión a bd
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;

using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;


namespace Persistencia_y_capa_de_negocio
{
    public class CADEvento
    {
        private static readonly CADEvento instancia = new CADEvento();
        public static CADEvento Instancia
        {
            get { return instancia; }
        }

        private string cadCon;  // Cadena de conexión conseguida desde app.config
        private SqlDataAdapter da;
        private SqlConnection c;
        private DataSet vdb;

        public CADEvento()
        {
            try
            {
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;

                vdb = new DataSet();
                c = new SqlConnection(cadCon);
                da = new SqlDataAdapter("Select * from eventos", c);

                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de edificios en local.
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Insertamos el evento dado en la base de datos
        /// </summary>
        /// <param name="ev">ENEvento del que tomaremos la información para rellenar la base de datos</param>
        public void InsertarEvento(ENEvento ev)
        {
            DataTable t = vdb.Tables["Evento"];
            DataRow r = t.NewRow();

            try
            {
                r["objeto"] = ev.IdObjeto;
                r["usuario"] = ev.IdUsuario;
                r["tipo"] = ev.Tipo;
                r["fechafin"] = ev.FechaFin;
                r["cantidad"] = ev.Cantidad;


                t.Rows.Add(r);

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Evento");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
                
        }

        /// <summary>
        /// Método que nos devuelve todos los eventos pendientes de la base de datos.
        /// </summary>
        /// <returns></returns>
        public ArrayList getEventos()
        {
            ArrayList lista = new ArrayList();

            DataTable t = new DataTable();
            t = vdb.Tables["Evento"];

            t.Clear();

            try
            {
                da = new SqlDataAdapter("select * from eventos", c);
                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de los eventos en local.

                t = vdb.Tables["Evento"];

                foreach (DataRow r in t.Rows)
                {
                    ENEvento ev = new ENEvento();

                    ev.Id = Convert.ToInt32(r["id"]);
                    ev.Cantidad = Convert.ToInt32(r["cantidad"]);
                    ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                    ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                    ev.Tipo = Convert.ToInt32(r["tipo"]);
                    ev.FechaFin = Convert.ToDateTime(r["fechafin"]);

                    lista.Add(ev);
                }
            }
            catch (Exception ex)
            {

            }

            return lista;
        }

        /// <summary>
        /// Devuelve un evento con la creación de defensas para un usuario dado
        /// </summary>
        /// <param name="usuario">Usuario del que queremos obtener la información</param>
        /// <returns>ENEvento con la información que hemos solicitado.</returns>
        public ENEvento getEventoUsuarioDefensa(int usuario)
        {
            DataTable t = vdb.Tables["Evento"];
            t.Clear();
            ENEvento ev = new ENEvento();

            string select = "usuario =" + usuario.ToString() + " and tipo=" + 2.ToString();

            try
            {
                da = new SqlDataAdapter("select * from eventos", c);



                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["Evento"];

                DataRow r = t.Select(select)[0];

                ev.Id = Convert.ToInt32(r["id"]);
                ev.Cantidad = 0;
                ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                ev.Tipo = Convert.ToInt32(r["tipo"]);
                ev.FechaFin = Convert.ToDateTime(r["fechafin"]);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            return ev;
        }

        /// <summary>
        /// Devuelve un evento con la creación de unidades para un usuario dado
        /// </summary>
        /// <param name="usuario">Usuario del que queremos el evento</param>
        /// <returns>ENEvento con la información solicitada</returns>
        public ENEvento getEventoUsuarioAstillero(int usuario)
        {
            ENEvento ev = new ENEvento();
            DataTable t = vdb.Tables["Evento"];
            t.Clear();

            string select = "usuario =" + usuario.ToString() + "and tipo=" + 1.ToString();

            try
            {
                da = new SqlDataAdapter("select * from eventos", c);

                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["Evento"];
                DataRow r = t.Select(select)[0];

                ev.Id = Convert.ToInt32(r["id"]);
                ev.Cantidad = Convert.ToInt32(r["cantidad"]);
                ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                ev.Tipo = Convert.ToInt32(r["tipo"]);
                ev.FechaFin = Convert.ToDateTime(r["fechafin"]);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            return ev;
        }

        /// <summary>
        /// Devuelve un evento de creación de recursos para un usuario dado
        /// </summary>
        /// <param name="usuario">usuario del que queremos su evento</param>
        /// <returns>ENEvento con la información solicitada</returns>
        public ENEvento getEventoUsuarioRecuros(int usuario)
        {
            ENEvento ev = new ENEvento();
            DataTable t = vdb.Tables["Evento"];
            t.Clear();

            string select = "usuario =" + usuario.ToString() + "and tipo=" + 0.ToString();

            try
            {
                da = new SqlDataAdapter("select * from eventos", c);

                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["Evento"];
                DataRow r = t.Select(select)[0];

                ev.Id = Convert.ToInt32(r["id"]);
                ev.Cantidad = 0;
                ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                ev.Tipo = Convert.ToInt32(r["tipo"]);
                ev.FechaFin = Convert.ToDateTime(r["fechafin"]);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            return ev;
        }

        /// <summary>
        /// Devuelve un evento de creación de investigación para el usuario dado
        /// </summary>
        /// <param name="usuario"></param>
        /// <returns></returns>
        public ENEvento getEventoUsuarioInvestigacion(int usuario)
        {
            DataTable t = vdb.Tables["Evento"];
            t.Clear();
            ENEvento ev = new ENEvento();

            string select = "usuario =" + usuario.ToString() + " and tipo=" + 3.ToString();

            try
            {
                da = new SqlDataAdapter("select * from eventos", c);



                da.Fill(vdb, "Evento");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["Evento"];

                DataRow r = t.Select(select)[0];

                ev.Id = Convert.ToInt32(r["id"]);
                ev.Cantidad = 0;
                ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                ev.Tipo = Convert.ToInt32(r["tipo"]);
                ev.FechaFin = Convert.ToDateTime(r["fechafin"]);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            return ev;
        }

        /// <summary>
        /// Método que nos devuelve una lista de los eventos que han caducado.
        /// </summary>
        /// <returns>ArrayList de elementos caducados</returns>
        public ArrayList getEventosCaducados()
        {
            ArrayList lista = new ArrayList();
            DataTable t = vdb.Tables["Evento"];

            string select = "fechafin <= \'" + DateTime.Now.ToString() + "\'";

            try
            {
                foreach (DataRow r in t.Select(select))
                {
                    ENEvento ev = new ENEvento();

                    ev.Id = Convert.ToInt32(r["id"]);
                    ev.Cantidad = Convert.ToInt32(r["cantidad"]);
                    ev.IdUsuario = Convert.ToInt32(r["usuario"]);
                    ev.IdObjeto = Convert.ToInt32(r["objeto"]);
                    ev.Tipo = Convert.ToInt32(r["tipo"]);
                    ev.FechaFin = Convert.ToDateTime(r["fechafin"]);

                    lista.Add(ev);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return lista;
        }

        /// <summary>
        /// Elimina el evento con la id que le pasamos por parámetro
        /// </summary>
        /// <param name="id">número identificativo del evento que queremos eliminar</param>
        public void EliminaEvento(int id)
        {
            string select = "id = " + id.ToString();

            DataTable t = vdb.Tables["Evento"];

            try
            {
                DataRow r = t.Select(select)[0];
                r.Delete();

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Evento");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Método que gestiona los eventos caducados y luego los elimina
        /// </summary>
        public void GestionaCaducados()
        {
            ArrayList lista = getEventosCaducados();

            foreach (ENEvento ev in lista)
            {
                switch (ev.Tipo)
                {
                    case 0:
                    {
                        // Edificio de recursos
                        CADEdificioUsuario.Instancia.MejoraEdificioUsuario(ev.IdUsuario, ev.IdObjeto);
                        EliminaEvento(ev.Id);
                        break;
                    }
                    case 1:
                    {
                        // Creación de unidades
                        CADUnidadesUsuario.Instancia.AnadirNumUnidadesUsuario(ev.IdUsuario, ev.IdObjeto, ev.Cantidad);
                        EliminaEvento(ev.Id);
                        break;
                    }
                    case 2:
                    {
                        // Edificio de defensa
                        CADEdificioUsuario.Instancia.MejoraEdificioUsuario(ev.IdUsuario, ev.IdObjeto);
                        EliminaEvento(ev.Id);
                        break;
                    }
                    case 3:
                    {
                        // Edificio de Investigacion
                        CADEdificioUsuario.Instancia.MejoraEdificioUsuario(ev.IdUsuario, ev.IdObjeto);
                        EliminaEvento(ev.Id);
                        break;
                    }
                }
            }
        }
    }
}
